home *** CD-ROM | disk | FTP | other *** search
- /* */
- /* PAGEDEMO.C */
- /* */
- /* There is a nonstandard 320x400 256 color VGA mode which has two pages. */
- /* This program demonstrates its use by setting up the mode, drawing to */
- /* the two pages, and flipping the pages for instanteous appearance of */
- /* of the graphics. */
- /* */
- /* A scanline function is included which shows how to take advantage of */
- /* memory plane masking to draw four pixels simutaneously. */
- /* */
- /* The mode setting routine is based upon Michael Abrash's demo which */
- /* can be found in PJ71.ARC in LDOS/lib 10. */
- /* */
- /* Thanks to Lawrence Gozum, Paul Lefevre, Joseph Wofford, Dave Angel, */
- /* Neil Rubenking, Brian Buck, and Eric Ace for their patience and help. */
- /* */
- /* Written for Turbo C. Compile with: tcc pagedemo */
- /* */
- /* Copyright Gary Boone 1991. Free for use in Free/Share/Comm. programs. */
- /* */
- /* Enjoy! */
- /* Gary Boone CIS:73040,3725 -- 23 April 1991 */
- /* */
- #include "dos.h" /* for getch() */
-
- void switchModes(int mode);
- void clearScreen(int page);
- void scanline(int page, int x1, int x2, int y, int color);
-
-
- void main(void)
- { int i,p,j;
-
- switchModes(0x13);
- for (i=0;i<400;i++) /* Draw a pattern on page 0 */
- scanline(0,0,i%320,i,i%256); /* while we watch. */
-
- for (i=0;i<400;i++) /* Draw another pattern on the */
- scanline(1,i%320,319,i,i%256); /* hidden page. */
-
- getch(); /* Wait for any key to be hit. */
- outport(0x3D4, 0x800C); /* Flip to other page, */
- getch(); /* and wait. */
-
- p=0; /* For fun, flip the pages */
- outportb(0x3D4, 0x0C); /* quickly. */
- for (i=0;i<500;i++)
- { outportb(0x3D5, 0x80*(p=1-p));
- for(j=1;j<1000;j++); /* delay so you can see the page */
- }
- getch();
- switchModes(3); /* Done. Back to text mode. */
- }
-
-
- void clearScreen(int page) /* how to quickly fill the screen with a color */
- { char far *addr;
- unsigned int i;
-
- addr = (char far*) (0xA0000000+0x8000000*page); /* point into video mem */
- outport(0x3C4,0x0f02); /* set all planes on */
- for (i=0;i<0x8000;i++)
- *(addr++)=(char) 0; /* four pixels at once! */
-
- }
-
- /* Scanline(): Draws horizontal lines quickly. */
- /* To increase speed, masks are determined from a look-up */
- /* table and written four at once, instead of being calculated */
- /* one at a time. Further, the middle pixels are masked and */
- /* written four at a time. (In this mode, there are four pixels*/
- /* at each address, one per plane. To pick one of the four, or */
- /* any combination, just set the plane mask accordingly.) */
- /* Note that if the pixels are (in order) a,b,c,d, then the */
- /* individual masks would be 0001b, 0010b, 0100b, and 1000b. */
- /* */
- void scanline(int page, int x1, int x2, int y, int color)
- { char far *addr;
- int plane,i,i2;
- char masks[]={1,3,7,15,2,6,14,14,4,12,12,12,8,8,8,8};
-
- addr = (char far*) (0xA0000000+0x8000000*page);
- addr+=320/4*y+x1/4; /* order matters! y*320/4 will wrap when y*320 */
- /* overflows the word length! */
- outportb(0x3C4, 2); /* point Sequence Controller to Map Mask reg. */
-
- /* first four pixels */
- i2=x2-x1; /* figure number of pixels after first */
- if (x2-x1>3) i2=3; /* but limit to first 4 pixels */
- plane=masks[(x1%4)*4+i2]; /* table is (x,y): x=start pix, y=length */
- outportb(0x3C5,plane); /* set the planes */
- *(addr++)=(char) color; /* draw! (then increment mem. pointer.) */
-
- /* middle four-byte groups */
- outportb(0x3C5,0xf); /* set all four planes */
- if ((x2-x1)/4>1) /* if there are middle 4 byte groups... */
- for (i=x1/4+1; i<x2/4; i++) /* draw all of 'em */
- *(addr++)=(char) color;
-
- /* do last four pixels */
- if (x1/4 != x2/4) /* if there is a last 4 byte group... */
- { plane=masks[x2%4]; /* obviously it starts at pixel 0... */
- outportb(0x3C5,plane);
- *(addr++)=(char) color;
- }
-
- }
-
-
-
-
- void switchModes(int mode) /* set mode including extended mode 13x */
- { unsigned int i, far *addr;
- union REGS regs;
-
- regs.x.ax = mode; /* normal mode set for all modes */
- int86(0x10, ®s, ®s);
-
- if (mode==0x13) /* modify mode 13 to get 320x400 */
- { outport(0x3C4, 0x0604); /* Seq. Cont. turn off Chain 4 and odd/even */
- outport(0x3CE, 0x4005); /* Gr. Cont.: turn off odd/even */
- outport(0x3CE, 0x0106); /* turn off chain */
- outport(0x3C4, 0x0F02); /* enable all planes */
- addr = (unsigned int far*) 0xA0000000; /* points to words so */
- for (i=0; i < 0x8000; i++) *addr++ = 0; /* erases both pages... */
- outport(0x3D4, 0x0009); /* CRTC: set max. scan line to 0 */
- outport(0x3D4, 0x2014); /* set normal word addressing */
- outport(0x3D4, 0xE317); /* turn on byte mode */
- }
-
- }
-
-
-